/**
 * @alias ProtoBuf.Util
 * @expose
 */
ProtoBuf.Util = (function () {
    "use strict";

    /**
     * ProtoBuf utilities.
     * @exports ProtoBuf.Util
     * @namespace
     */
    var Util = {};

    /**
     * Flag if running in node or not.
     * @type {boolean}
     * @const
    * @expose
     */
    Util.IS_NODE = !!(
        typeof process === 'object' && process + '' === '[object process]' && !process['browser']
    );

    /**
     * Constructs a XMLHttpRequest object.
     * @return {XMLHttpRequest}
     * @throws {Error} If XMLHttpRequest is not supported
     * @expose
     */
    Util.XHR = function () {
        // No dependencies please, ref: http://www.quirksmode.org/js/xmlhttp.html
        var XMLHttpFactories = [
            function () {
                return new XMLHttpRequest()
            },
            function () {
                return new ActiveXObject("Msxml2.XMLHTTP")
            },
            function () {
                return new ActiveXObject("Msxml3.XMLHTTP")
            },
            function () {
                return new ActiveXObject("Microsoft.XMLHTTP")
            }
        ];
        /** @type {?XMLHttpRequest} */
        var xhr = null;
        for (var i = 0;i < XMLHttpFactories.length; i++) {
            try {
                xhr = XMLHttpFactories[i]();
            }
            catch (e) {
                continue;
            }
            break;
        }
        if (!xhr)
            throw Error("XMLHttpRequest is not supported");
        return xhr;
    };

    /**
     * Fetches a resource.
     * @param {string} path Resource path
     * @param {function(?string)=} callback Callback receiving the resource's contents. If omitted the resource will
     *   be fetched synchronously. If the request failed, contents will be null.
     * @return {?string|undefined} Resource contents if callback is omitted (null if the request failed), else undefined.
     * @expose
     */
    Util.fetch = async function (path, callback) {
        if (callback && typeof callback != 'function') {
            callback = null;
        }
        if (!ProtoBuf.resourceManager) {
            return;
        }

        let value = await ProtoBuf.resourceManager.getRawFd(path)

        console.log(ProtoBuf.TAG, "getRawFd =" + JSON.stringify(value))
        let buf = new ArrayBuffer(value.length)
        let num = fs.readSync(value.fd, buf)
        console.log(ProtoBuf.TAG, "readSync length =" + num)

        console.log(ProtoBuf.TAG, "file content = " + buffer.from(buf).toString("utf-8"))

        return buffer.from(buf).toString("utf-8")


        // if (Util.IS_NODE) {
        //     var fs = require("fs");
        //     if (callback) {
        //         fs.readFile(path, function(err, data) {
        //             if (err)
        //                 callback(null);
        //             else
        //                 callback(""+data);
        //         });
        //     } else
        //         try {
        //             return fs.readFileSync(path);
        //         } catch (e) {
        //             return null;
        //         }
        // } else {
        //     var xhr = Util.XHR();
        //     xhr.open('GET', path, callback ? true : false);
        //     // xhr.setRequestHeader('User-Agent', 'XMLHTTP/1.0');
        //     xhr.setRequestHeader('Accept', 'text/plain');
        //     if (typeof xhr.overrideMimeType === 'function') xhr.overrideMimeType('text/plain');
        //     if (callback) {
        //         xhr.onreadystatechange = function() {
        //             if (xhr.readyState != 4) return;
        //             if (/* remote */ xhr.status == 200 || /* local */ (xhr.status == 0 && typeof xhr.responseText === 'string'))
        //                 callback(xhr.responseText);
        //             else
        //                 callback(null);
        //         };
        //         if (xhr.readyState == 4)
        //             return;
        //         xhr.send(null);
        //     } else {
        //         xhr.send(null);
        //         if (/* remote */ xhr.status == 200 || /* local */ (xhr.status == 0 && typeof xhr.responseText === 'string'))
        //             return xhr.responseText;
        //         return null;
        //     }
        // }
    };

    /**
     * Converts a string to camel case.
     * @param {string} str
     * @returns {string}
     * @expose
     */
    Util.toCamelCase = function (str) {
        return str.replace(/_([a-zA-Z])/g, function ($0, $1) {
            return $1.toUpperCase();
        });
    };

    return Util;
})();
